<?php
/**
 * Author:xsc
 * Time:2023/11/21 9:43
 */

namespace App\Jobs;

use App\Service\Common\ResponseService;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Common\Tools;
use Illuminate\Support\Facades\Log;
use App\Repository\OpenPlatformRepo;
use App\Repository\SpecialRepo;
use App\Repository\OpenCallbackRepo;
use App\Traits\HttpHelper;

class ModifySpecialCallbackJob extends Job
{
    use  InteractsWithQueue, Queueable, SerializesModels, HttpHelper;

    /**
     * 任务可尝试的次数
     */
    public $tries = 3;

    /**
     * 任务失败前允许的最大异常数
     */
    public $maxExceptions = 3;

    /**
     * 在超时之前任务可以运行的秒数
     */
    public $timeout = 10;

    private $special_id;

    public function __construct(int $special_id)
    {
        $this->special_id = $special_id;
    }

    public function handle()
    {
        $special_id = $this->special_id;

        Log::info('[藏品状态更新回调]' . $special_id);

        $special = SpecialRepo::getInstance()->detail($special_id);
        if (!$special) {
            Log::info('[藏品状态更新回调]失败' . $special_id . '藏品不存在');
            return false;
        }

        if (!$special['access_mid']) {
            Log::info('[藏品状态更新回调]失败' . $special_id . '_' . $special['mer_id'] . '创作者未绑定商户');
            return false;
        }

        if (!$special['platform_id']) {
            Log::info('[藏品状态更新回调]失败' . $special_id . '_' . $special['access_mid'] . '商户未绑定平台');
            return false;
        }

        $platform_id = $special['platform_id'];
        $platform = OpenPlatformRepo::getInstance()->getInfo($platform_id);
        if (!$platform) {
            Log::info('[藏品状态更新回调]失败' . $special_id . '_' . $platform_id . '平台不存在');
            return false;
        }

        if (!$platform['callback_url']) {
            Log::info('[藏品状态更新回调]失败' . $special_id . '_' . $platform_id . '平台未配置回调地址');
            return false;
        }

        try {
            $request = [
                'action'       => 'modify_special',
                'special_id'   => $special_id,
                'apply_status' => $special['apply_status'],
                'status'       => $special['status'],
                'reason'       => $special['reason'],
            ];

            // 1.入库
            $callback_no = Tools::build_hash_no();
            $data1 = [
                'callback_no' => $callback_no,
                'platform_id' => $platform_id,
                'request'     => json_encode($request, 256),
                'create_time' => date('Y-m-d H:i:s'),
            ];
            $res1 = OpenCallbackRepo::getInstance()->save($data1);
            if (!$res1) {
                throw new \Exception('入库失败' . json_encode($data1, 256));
            }

            // 2.回调通知
            $callback_url = $platform['callback_url'];
            $callback_request = ResponseService::getInstance()->return(0, '处理成功', $request, $platform['platform_no']);
            $res2 = $this->sendPost($callback_url, $callback_request)->getBody()->getContents();
            $res2 = json_decode($res2, true);
            if (!$res2) {
                throw new \Exception('回调失败,无响应');
            }

            if (isset($res2['error_code']) && $res2['error_code'] == 0) {
                // 3.更新数据
                $data3 = [
                    'response'    => json_encode($res2, 256),
                    'update_time' => date('Y-m-d H:i:s'),
                ];
                $res3 = OpenCallbackRepo::getInstance()->save($data3, $res1);

                Log::info('[藏品状态更新回调]成功' . $special_id);
            } else {
                throw new \Exception('回调失败' . json_encode($res2, 256));
            }
        } catch (\Exception $e) {
            Log::info('[藏品状态更新回调]失败' . $special_id . '_' . $platform_id . '_' . $e->getFile() . '_' . $e->getLine() . '_' . $e->getMessage());

            // 30s之后再次加入队列
            return $this->release(30);
        }
    }
}
